﻿using jvm.instructions.common;
using jvm.rtda;
using jvm.rtda.heap;
using jvm.rtda.heap.clazz;
using jvm.rtda.heap.clazz.cp;
using jvm.rtda.heap.clazz.method;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace jvm.instructions.references
{
    class INVOKE_INTERFACE : Instruction
    {
        uint index;
        //byte count;
        //byte zero;

        public override void FetchOperands(ByteCodeReader reader)
        {
            index = reader.ReadUint16();
            reader.ReadUint8();
            reader.ReadUint8();
        }

        public override void Execute(JFrame frame)
        {
            JConstantPool pool = frame.method.jClass.constantPool;
            InterfaceMethodRef methodRef = pool.GetConstant<InterfaceMethodRef>(index);
            JMethod method = methodRef.ResolvedInterfaceMethod();

            if (method.Is(AccessFlags.ACC_STATIC) || method.Is(AccessFlags.ACC_PRIVATE))
            {
                Console.WriteLine("java.lang.InCompatibleClassChangeError");
                Environment.Exit(0);
            }

            JObject thisObj = frame.operandStack.GetRefFromTop(method.argCount - 1);
            if (thisObj == null)
            {
                Console.WriteLine("java.lang.NullPointerException");
                Environment.Exit(0);
            }

            if (!thisObj.jClass.IsImplements(methodRef.ResolvedClass()))
            {
                Console.WriteLine("java.lang.InCompatibleClassChangeError");
                Environment.Exit(0);
            }

            // 动态绑定
            JMethod methodToBeInvoked = MethodLookUp.LookUpMethodInClass(thisObj.jClass, methodRef.name, methodRef.descriptor);
            if (methodToBeInvoked == null || methodToBeInvoked.Is(AccessFlags.ACC_ABSTRACT))
            {
                Console.WriteLine("java.lang.AbstractMethodError");
                Environment.Exit(0);
            }
            InvokeUtil.InvokeMethod(frame, methodToBeInvoked);
        }

    }
}
